<template>
  <!-- 使用 ElPopover 解决边界问题，固定边框避免抖动 -->
  <el-popover
    :visible="visible"
    :virtual-ref="virtualRef"
    trigger="manual"
    placement="bottom-start"
    :width="160"
    :teleported="true"
    :show-arrow="false"
    popper-class="context-menu-popover"
    :transition="'none'"
    @hide="$emit('hide')"
  >
    <div class="context-menu-content">
      <!-- 文件/文件夹操作 -->
      <div class="menu-item" @click="$emit('open')" v-if="displaySelectedItem">
        <el-icon><FolderOpened /></el-icon>
        <span>打开</span>
      </div>

      <div
        class="menu-item"
        @click="$emit('openWith')"
        v-if="displaySelectedItem?.type === 'file'"
      >
        <el-icon><Document /></el-icon>
        <span>打开方式</span>
      </div>

      <div class="menu-divider" v-if="displaySelectedItem"></div>

      <div class="menu-item" @click="$emit('cut')" v-if="displaySelectedItem">
        <el-icon><Scissor /></el-icon>
        <span>剪切</span>
      </div>

      <div class="menu-item" @click="$emit('copy')" v-if="displaySelectedItem">
        <el-icon><DocumentCopy /></el-icon>
        <span>复制</span>
      </div>

      <div
        class="menu-item"
        @click="handlePasteClick"
        :class="{ disabled: !canPaste }"
      >
        <el-icon><DocumentCopy /></el-icon>
        <span>粘贴</span>
      </div>

      <div class="menu-divider"></div>

      <div
        class="menu-item"
        @click="$emit('delete')"
        v-if="displaySelectedItem"
      >
        <el-icon><Delete /></el-icon>
        <span>删除</span>
      </div>

      <div
        class="menu-item"
        @click="$emit('rename')"
        v-if="displaySelectedItem"
      >
        <el-icon><Edit /></el-icon>
        <span>重命名</span>
      </div>

      <!-- 空白区域操作 -->
      <div
        class="menu-item"
        @click="$emit('newFolder')"
        v-if="!displaySelectedItem"
      >
        <el-icon><FolderAdd /></el-icon>
        <span>新建文件夹</span>
      </div>

      <div
        class="menu-item"
        @click="$emit('newFile')"
        v-if="!displaySelectedItem"
      >
        <el-icon><DocumentAdd /></el-icon>
        <span>新建文件</span>
      </div>

      <div class="menu-item" @click="$emit('refresh')">
        <el-icon><Refresh /></el-icon>
        <span>刷新</span>
      </div>

      <div class="menu-divider" v-if="displaySelectedItem"></div>

      <div
        class="menu-item"
        @click="$emit('properties')"
        v-if="displaySelectedItem"
      >
        <el-icon><Setting /></el-icon>
        <span>属性</span>
      </div>
    </div>
  </el-popover>
</template>

<script setup lang="ts">
import { computed } from "vue";
import {
  FolderOpened,
  Document,
  Scissor,
  DocumentCopy,
  Delete,
  Edit,
  FolderAdd,
  DocumentAdd,
  Refresh,
  Setting,
} from "@element-plus/icons-vue";

interface FileItem {
  name: string;
  type: "file" | "folder";
  size?: string;
  modifiedDate: string;
  extension?: string;
  path: string;
}

interface Position {
  x: number;
  y: number;
}

const props = defineProps<{
  visible: boolean;
  position: Position;
  selectedItem?: FileItem | null;
  canPaste?: boolean;
}>();

const emit = defineEmits<{
  open: [];
  openWith: [];
  cut: [];
  copy: [];
  paste: [];
  delete: [];
  rename: [];
  newFolder: [];
  newFile: [];
  refresh: [];
  properties: [];
  hide: [];
}>();

// 创建稳定的虚拟引用元素用于定位，防止位置跳动
const createVirtualRef = (x: number, y: number) => ({
  getBoundingClientRect: () => ({
    x,
    y,
    top: y,
    left: x,
    bottom: y,
    right: x,
    width: 0,
    height: 0,
  }),
});

// 保持当前位置，避免隐藏时位置重置
let stablePosition = { x: 0, y: 0 };
// 保持稳定的菜单内容，防止显示期间内容切换
let stableSelectedItem: FileItem | null = null;

const virtualRef = computed(() => {
  // 只在菜单显示时更新位置，隐藏时保持稳定位置
  if (props.visible) {
    stablePosition = { ...props.position };
    // 菜单显示时锁定内容，防止后续变化
    stableSelectedItem = props.selectedItem || null;
  }
  // 无论显示还是隐藏，都使用稳定位置，防止跳动
  return createVirtualRef(stablePosition.x, stablePosition.y);
});

// 使用稳定的选中项状态，确保菜单显示期间内容不变
const displaySelectedItem = computed(() => {
  // 当菜单可见时，使用锁定的稳定状态；不可见时返回 null
  return props.visible ? stableSelectedItem : null;
});

// 处理粘贴点击，只有在可粘贴时才触发事件
const handlePasteClick = () => {
  if (props.canPaste) {
    emit("paste");
  }
};
</script>

<style lang="scss">
// 右键菜单 popover 样式 - 固定边框避免抖动
.context-menu-popover {
  padding: 0 !important;
  min-width: 160px !important;
  &.el-popover.el-popper {
    border: none;
  }

  .context-menu-content {
    padding: 4px 0;
    user-select: none;
  }

  .menu-item {
    display: flex;
    align-items: center;
    padding: 8px 16px;
    cursor: pointer;
    font-size: 14px;
    color: #333;
    transition: none;

    &:hover {
      background-color: #f5f7fa;
    }

    &.disabled {
      color: #c0c4cc;
      cursor: not-allowed;

      &:hover {
        background-color: transparent;
      }
    }

    .el-icon {
      margin-right: 8px;
      font-size: 16px;
    }
  }

  .menu-divider {
    height: 1px;
    background-color: #e4e7ed;
    margin: 4px 0;
  }
}
</style>
